package proxysvc

import (
	"bytes"
	"encoding/json"
	corev1 "gluenet/internal/agent/api/core/v1"
	"io"
	"net/http"
	"net/url"
	"strings"
)

// ProxyRequest means you can customize the request.
//
//	example:corev1.ProxyRequest{
//			HttpUrl: "https://httpbin.org/get",
//			Method:  "GET",
//			Params: map[string]string{
//				"start": "1660094966",
//			},
func (svc *Service) ProxyRequest(proxyReq corev1.ProxyRequest) corev1.CommonResp {
	var err error
	switch proxyReq.Method {
	case "GET":
		params := url.Values{}
		if len(proxyReq.Params) != 0 {
			for k, v := range proxyReq.Params {
				params.Set(k, v)
			}
		}
		if strings.Contains(proxyReq.HttpUrl, "?") {
			proxyReq.HttpUrl += "&" + params.Encode()
		} else {
			proxyReq.HttpUrl += "?" + params.Encode()
		}
		resp, err := http.Get(proxyReq.HttpUrl)
		if err != nil {
			goto ErrProcess
		}
		defer resp.Body.Close()
		data, err := io.ReadAll(resp.Body)
		if err != nil {
			goto ErrProcess
		}
		return corev1.NewCommonSuccessRespWithData(data)
	default:
		jsonBody, _ := json.Marshal(proxyReq.Body)
		req, err := http.NewRequest(proxyReq.Method, proxyReq.HttpUrl, bytes.NewReader(jsonBody))
		if err != nil {
			goto ErrProcess
		}
		req.Header.Set("Content-type", "application/json")
		if proxyReq.Headers != nil {
			for key, val := range proxyReq.Headers {
				req.Header.Add(key, val)
			}
		}
		resp, err := http.DefaultClient.Do(req)
		if err != nil {
			goto ErrProcess
		}
		defer resp.Body.Close()
		data, err := io.ReadAll(resp.Body)
		if err != nil {
			goto ErrProcess
		}
		return corev1.NewCommonSuccessRespWithData(data)
	}
ErrProcess:
	svc.logger.Errorf(err.Error())
	return corev1.NewCommonFailureResp(err.Error())
}

// ProxyGet provides a get request,you can both use complete url or use params to build url,
// also you can combine them.
func (svc *Service) ProxyGet(proxyReq corev1.ProxyGet) corev1.CommonResp {
	var data []byte
	params := url.Values{}
	//Determine if there are params, if so, append it to the end of the url
	if len(proxyReq.Params) != 0 {
		for k, v := range proxyReq.Params {
			params.Set(k, v)
		}
	}
	if strings.Contains(proxyReq.HttpUrl, "?") {
		proxyReq.HttpUrl += "&" + params.Encode()
	} else {
		proxyReq.HttpUrl += "?" + params.Encode()
	}
	response, err := http.Get(proxyReq.HttpUrl)
	if err != nil {
		goto ErrProcess
	}
	data, err = io.ReadAll(response.Body)
	if err != nil {
		goto ErrProcess
	}
	return corev1.NewCommonSuccessRespWithData(data)
ErrProcess:
	svc.logger.Errorf(err.Error())
	return corev1.NewCommonFailureResp(err.Error())
}

func (svc *Service) ProxyPost(proxyReq corev1.ProxyPost) corev1.CommonResp {
	var data []byte
	bodyBytes, _ := json.Marshal(proxyReq.Body)
	response, err := http.Post(proxyReq.HttpUrl, "application/json", bytes.NewReader(bodyBytes))
	if err != nil {
		goto ErrProcess
	}
	data, err = io.ReadAll(response.Body)
	if err != nil {
		goto ErrProcess
	}
	return corev1.NewCommonSuccessRespWithData(data)
ErrProcess:
	svc.logger.Errorf(err.Error())
	return corev1.NewCommonFailureResp(err.Error())
}
